package com.open.cloud.rbac.service.menu.impl;

import cn.hutool.core.lang.Snowflake;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.open.cloud.rbac.entity.menu.CoreMenu;
import com.open.cloud.rbac.entity.menu.CoreMenuInterfaceRel;
import com.open.cloud.rbac.entity.permission.CorePermissionMenuRel;
import com.open.cloud.rbac.mapper.menu.CoreMenuInterfaceRelMapper;
import com.open.cloud.rbac.mapper.menu.CoreMenuMapper;
import com.open.cloud.rbac.mapper.permission.CorePermissionMenuRelMapper;
import com.open.cloud.rbac.mapper.role.ViewOrgRolePermissionMenuMapper;
import com.open.cloud.rbac.mapper.role.ViewPostRolePermissionMenuMapper;
import com.open.cloud.rbac.mapper.role.ViewUserRolePermissionMenuMapper;
import com.open.cloud.rbac.object.menu.CoreMenuDto;
import com.open.cloud.rbac.object.menu.CoreMenuInterfaceRelDto;
import com.open.cloud.rbac.object.menu.CoreMenuSelectDto;
import com.open.cloud.rbac.object.menu.CoreMenuVo;
import com.open.cloud.rbac.service.menu.ICoreMenuService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author wangzengzhou01
 * @since 2024-12-23
 */
@Service
public class CoreMenuServiceImpl extends ServiceImpl<CoreMenuMapper, CoreMenu>
        implements ICoreMenuService {

    @Resource
    private CoreMenuMapper menuMapper;

    @Resource
    private Snowflake snowflake;

    @Resource
    private CorePermissionMenuRelMapper permissionMenuRelMapper;

    @Resource
    private CoreMenuInterfaceRelMapper menuInterfaceRelMapper;

    @Resource
    private ViewOrgRolePermissionMenuMapper orgRolePermissionMenuMapper;

    @Resource
    private ViewPostRolePermissionMenuMapper postRolePermissionMenuMapper;

    @Resource
    private ViewUserRolePermissionMenuMapper userRolePermissionMenuMapper;

    /**
     * 新增菜单信息
     *
     * @param menuDto
     * @return
     */
    @Override
    public JSONObject addMenuItem(CoreMenuDto menuDto) {
        CoreMenu coreMenu = new CoreMenu();
        BeanUtils.copyProperties(menuDto, coreMenu);
        coreMenu.setId(snowflake.nextIdStr());
        coreMenu.setCreateTime(new Date());
        coreMenu.setCreateBy("admin");
        coreMenu.setUpdateTime(new Date());
        coreMenu.setUpdateBy("admin");
        int i = menuMapper.insert(coreMenu);
        JSONObject result = new JSONObject();
        if (i > 0) {
            result.put("code", 200);
            result.put("message", "创建成功");
        } else {
            result.put("code", 500);
            result.put("message", "创建失败");
        }
        return result;
    }

    /**
     * 修改菜单信息
     *
     * @param menuDto
     * @return
     */
    @Override
    public JSONObject updateMenuItem(CoreMenuDto menuDto) {
        CoreMenu coreMenu = new CoreMenu();
        BeanUtils.copyProperties(menuDto, coreMenu);
        coreMenu.setUpdateTime(new Date());
        coreMenu.setUpdateBy("admin");
        int i = menuMapper.updateById(coreMenu);
        JSONObject resultObj = new JSONObject();
        if (i > 0) {
            resultObj.put("code", 200);
            resultObj.put("message", "修改成功");
        } else {
            resultObj.put("code", 500);
            resultObj.put("message", "修改失败");
        }
        return resultObj;
    }

    /**
     * 删除菜单
     *
     * @param menuId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject deleteMenuItem(String menuId) {
        LambdaQueryWrapper menuQuery = Wrappers.<CoreMenu>lambdaQuery()
                .eq(CoreMenu::getParentId, menuId);
        List list = menuMapper.selectList(menuQuery);
        JSONObject result = new JSONObject();
        if (list.size() > 0) {
            result.put("code", 500);
            result.put("message", "该菜单下存在子菜单，无法删除");
        } else {
            LambdaQueryWrapper menuInterfaceRelQuery = Wrappers.<CoreMenuInterfaceRel>lambdaQuery()
                    .eq(CoreMenuInterfaceRel::getMenuId, menuId);
            menuInterfaceRelMapper.delete(menuInterfaceRelQuery);

            LambdaQueryWrapper permissionMenuRelQuery = Wrappers.<CorePermissionMenuRel>lambdaQuery()
                    .eq(CorePermissionMenuRel::getMenuId, menuId);
            permissionMenuRelMapper.delete(permissionMenuRelQuery);

            int i = this.baseMapper.deleteById(menuId);
            if (i > 0) {
                result.put("code", 200);
                result.put("message", "删除成功");
            } else {
                result.put("code", 500);
                result.put("message", "删除失败");
            }
        }
        return result;
    }

    /**
     * 查询菜单树
     *
     * @param menuSelectDto
     * @return
     */
    @Override
    public List<CoreMenuVo> getMenuTree(CoreMenuSelectDto menuSelectDto) {
        LambdaQueryWrapper<CoreMenu> menuQuery = Wrappers.<CoreMenu>lambdaQuery()
                .orderByDesc(CoreMenu::getSort);
        List<CoreMenu> menuList = menuMapper.selectList(menuQuery);
        List<CoreMenuVo> menuVoList = getMenuVoList(menuList, "0", "");
        return menuVoList;
    }

    private List<CoreMenuVo> getMenuVoList(List<CoreMenu> list, String parentId, String parentName) {
        List<CoreMenuVo> dataList = new ArrayList<>();
        list.forEach(item -> {
            if (item.getParentId().equals(parentId)) {
                CoreMenuVo menuVo = new CoreMenuVo();
                BeanUtils.copyProperties(item, menuVo);
                menuVo.setParentName(parentName);
                List<CoreMenuVo> children = getMenuVoList(list, item.getId(), item.getMenuName());
                menuVo.setChildren(children);
                dataList.add(menuVo);
            }
        });
        return dataList;
    }

    /**
     * 根据菜单Id查询相关接口
     *
     * @param menuId
     * @return
     */
    @Override
    public List<CoreMenuInterfaceRel> getMenuRelInterface(String menuId) {
        LambdaQueryWrapper<CoreMenuInterfaceRel> menuQuery = Wrappers.<CoreMenuInterfaceRel>lambdaQuery()
                .eq(CoreMenuInterfaceRel::getMenuId, menuId);
        List<CoreMenuInterfaceRel> relList = menuInterfaceRelMapper.selectList(menuQuery);
        return relList;
    }

    /**
     * 设置菜单接口关联关系
     *
     * @param menuInterfaceRelDto
     * @return
     */
    @Override
    public JSONObject setMenuRelInterface(CoreMenuInterfaceRelDto menuInterfaceRelDto) {
        Boolean isSelect = menuInterfaceRelDto.getIsSelect();
        JSONObject result = new JSONObject();
        if (isSelect) {
            CoreMenuInterfaceRel menuInterfaceRel = new CoreMenuInterfaceRel();
            BeanUtils.copyProperties(menuInterfaceRelDto, menuInterfaceRel);
            menuInterfaceRel.setId(snowflake.nextIdStr());
            menuInterfaceRel.setCreateTime(new Date());
            int insert = menuInterfaceRelMapper.insertMenuRelInterface(menuInterfaceRel);
            if (insert > 0) {
                result.put("code", 200);
                result.put("message", "已关联");
            } else {
                result.put("code", 500);
                result.put("message", "关联失败");
            }
        } else {
            LambdaQueryWrapper<CoreMenuInterfaceRel> menuQuery = Wrappers.<CoreMenuInterfaceRel>lambdaQuery()
                    .eq(CoreMenuInterfaceRel::getMenuId, menuInterfaceRelDto.getMenuId())
                    .eq(CoreMenuInterfaceRel::getModuleName, menuInterfaceRelDto.getModuleName())
                    .eq(CoreMenuInterfaceRel::getRequestServer, menuInterfaceRelDto.getRequestServer())
                    .eq(CoreMenuInterfaceRel::getRequestUrl, menuInterfaceRelDto.getRequestUrl())
                    .eq(CoreMenuInterfaceRel::getUniqueUrl, menuInterfaceRelDto.getUniqueUrl());
            int delete = menuInterfaceRelMapper.delete(menuQuery);
            if (delete > 0) {
                result.put("code", 200);
                result.put("message", "已解除关联");
            } else {
                result.put("code", 500);
                result.put("message", "解除关联失败");
            }
        }
        return result;
    }

    /**
     * 根据角色Id获取菜单列表
     *
     * @param roleId
     * @return
     */
    @Override
    public List<CoreMenu> getMenuListByRoleId(String roleId) {
        List<CoreMenu> data = menuMapper.selectMenuByRoleId(roleId);
        return data;
    }

    /**
     * 根据组织Id获取菜单列表
     *
     * @param orgId
     * @return
     */
    @Override
    public List<CoreMenuVo> getMenuListByOrgId(String orgId) {
        List<String> menuIds = orgRolePermissionMenuMapper.selectMenuIdByOrgId(orgId);
        List<CoreMenuVo> menuVoList = null;
        if (menuIds.size() > 0) {
            List<CoreMenu> menuList = menuMapper.selectMenuInIds(menuIds);
            menuVoList = getMenuVoList(menuList, "0", "");
        }
        return menuVoList;
    }

    /**
     * 根据postId获取菜单列表
     *
     * @param postId
     * @return
     */
    @Override
    public List<CoreMenuVo> getMenuListByPostId(String postId) {
        List<String> menuIds = postRolePermissionMenuMapper.selectMenuIdByPostId(postId);
        List<CoreMenuVo> menuVoList = null;
        if (menuIds.size() > 0) {
            List<CoreMenu> menuList = menuMapper.selectMenuInIds(menuIds);
            menuVoList = getMenuVoList(menuList, "0", "");
        }
        return menuVoList;
    }

    /**
     * 根据userId获取菜单列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<CoreMenuVo> getMenuListByUserId(String userId) {
        List<String> menuIds = userRolePermissionMenuMapper.selectMenuIdByUserId(userId);
        List<String> orgMenuIds = orgRolePermissionMenuMapper.selectMenuIdByUserId(userId);
        List<String> postMenuIds = postRolePermissionMenuMapper.selectMenuIdByUserId(userId);
        Set<String> set = new HashSet<>(menuIds);
        set.addAll(orgMenuIds);
        set.addAll(postMenuIds);
        List<String> list = new ArrayList<>(set);
        List<CoreMenuVo> menuVoList = null;
        if (menuIds.size() > 0) {
            List<CoreMenu> menuList = menuMapper.selectMenuInIds(list);
            menuVoList = getMenuVoList(menuList, "0", "");
        }
        return menuVoList;
    }

}
